package com.numberone.iotplatform.service.impl;


import com.fasterxml.jackson.databind.ObjectMapper;
import com.numberone.iotplatform.entity.DeviceEvent;
import com.numberone.iotplatform.repository.DeviceEventRepository;
import com.numberone.iotplatform.service.DeviceEventService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import javax.persistence.criteria.Predicate;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;

/**
 * DeviceEventService 接口的实现类。
 */
@Service
public class DeviceEventServiceImpl implements DeviceEventService {

    // 注入数据访问仓库
    @Autowired
    private DeviceEventRepository deviceEventRepository;



    /**
     * 实现带有动态筛选条件的分页查询。
     * 使用 JPA Specification API 来动态构建 WHERE 子句。
     */
    @Override
    public Page<DeviceEvent> findEventsByDeviceId(
            Long deviceId,
            String eventType,
            LocalDateTime startTime,
            LocalDateTime endTime,
            Pageable pageable) {

        // 创建一个 Specification 对象，用于定义查询条件
        Specification<DeviceEvent> spec = (root, query, criteriaBuilder) -> {
            // 创建一个 Predicate 列表，用于存放所有的查询条件
            List<Predicate> predicates = new ArrayList<>();

            // 1. 添加必需的条件：deviceId 必须匹配
            predicates.add(criteriaBuilder.equal(root.get("deviceId"), deviceId));

            // 2. 添加可选条件：如果 eventType 字符串不为空，则添加类型匹配条件
            if (StringUtils.hasText(eventType)) {
                predicates.add(criteriaBuilder.equal(root.get("eventType"), eventType));
            }

            // 3. 添加可选条件：如果 startTime 不为 null，则添加时间大于等于条件
            if (startTime != null) {
                predicates.add(criteriaBuilder.greaterThanOrEqualTo(root.get("eventTime"), startTime));
            }

            // 4. 添加可选条件：如果 endTime 不为 null，则添加时间小于等于条件
            if (endTime != null) {
                predicates.add(criteriaBuilder.lessThanOrEqualTo(root.get("eventTime"), endTime));
            }

            // 将所有条件用 AND 连接起来，并返回
            return criteriaBuilder.and(predicates.toArray(new Predicate[0]));
        };

        // 调用 repository 的 findAll 方法，传入 Specification 和 Pageable 对象
        return deviceEventRepository.findAll(spec, pageable);
    }
}